//
//  SharedMemory.m
//  ClienteHabitueIOS
//
//  Created by Mauro Carreño on 5/29/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "SharedMemory.h"
#import "User.h"
#import "AuditType.h"
#import "Audit.h"
#import "PointOfSell.h"
#import "ControlVariables.h"

@implementation SharedMemory

@synthesize errorMessage;
@synthesize errorMessageTitle;
@synthesize commitPointOfSellInternalId;
@synthesize userIndex;
@synthesize pointOfSellIndex;
@synthesize auditTypeIndex;
@synthesize mNewPointOfSell;
@synthesize pointsOfSell;
@synthesize auditTypes;
@synthesize users;
@synthesize auditTypesDone;
@synthesize documentsPath;
@synthesize lastGoodLocation;

static SharedMemory *sharedInstance = nil;


- (void) dealloc
{
    [errorMessage release], errorMessage = nil ;
    [errorMessageTitle release], errorMessageTitle = nil ;
    [commitPointOfSellInternalId release], commitPointOfSellInternalId = nil ;
    [mNewPointOfSell release], mNewPointOfSell = nil ;
    [pointsOfSell release], pointsOfSell = nil ;
    [auditTypes release], auditTypes = nil ;
    [users release], users = nil ;
    [auditTypesDone release], auditTypesDone = nil ;
    [documentsPath release], documentsPath = nil;
    [lastGoodLocation release], lastGoodLocation = nil;
    sharedInstance = nil;
    [super dealloc];
}


- (id)init
{
    self = [super init];
    
    if (self) {
        self.errorMessageTitle = @"";
        self.errorMessage = @"";
        
        self.commitPointOfSellInternalId = @"";
        self.userIndex = -1;
        self.pointOfSellIndex = 0;
        self.auditTypeIndex = -1;
        self.mNewPointOfSell = nil;
        self.pointsOfSell = [[[NSMutableArray alloc] init ] autorelease];
        self.auditTypes = [[[NSMutableArray alloc] init ] autorelease];
        self.users = [[[NSMutableArray alloc] init ] autorelease];
        self.auditTypesDone = [[[NSMutableArray alloc] init ] autorelease];
        NSArray *writablePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        self.documentsPath = [writablePaths lastObject];
        self.lastGoodLocation = nil;
    }
    
    return self;
}



- (User*) getUser
{
    if(self.userIndex==-1)
        return nil;
    return [users objectAtIndex:self.userIndex];
}

- (PointOfSell*) getPointOfSell
{
    if(self.pointOfSellIndex==-1)
        return nil;
    if(self.pointOfSellIndex==-2)
        return self.mNewPointOfSell;
    if(self.pointOfSellIndex >= [self.pointsOfSell count])
        self.pointOfSellIndex = 0;
    return [self.pointsOfSell objectAtIndex:self.pointOfSellIndex] ;
}

- (AuditType*) getAuditType
{
    if(self.auditTypeIndex==-1)
        return nil;
    return [self.auditTypes objectAtIndex:auditTypeIndex];
}

+ (AuditType*) findAuditTypeByExternalId:(NSString*) externalId
{
    if([externalId isEqualToString:@""])
        return nil;
    for (AuditType* t in sharedInstance.auditTypes) {
        if([t.externalId isEqualToString:externalId])
            return t;
    }
    return nil;
}


+ (PointOfSell*) findPDVByInternalId:(NSString*) internalIdPDV
{
    for (PointOfSell* pdv in sharedInstance.pointsOfSell) {
        if([pdv.internalId isEqualToString:internalIdPDV])
            return pdv;
    }
    return nil;
}

+(void)createDirectory:(NSString *)directoryName
{
    SharedMemory* mem = [SharedMemory sharedInstance];
    NSString *filePathAndDirectory = [mem.documentsPath stringByAppendingPathComponent:directoryName];
    NSError *error;
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePathAndDirectory]) {
        NSLog(@"Dir content: %@", [[NSFileManager defaultManager] contentsOfDirectoryAtPath:filePathAndDirectory error:&error]);
        return;
    }
    
    if (![[NSFileManager defaultManager] createDirectoryAtPath:filePathAndDirectory
                                   withIntermediateDirectories:NO
                                                    attributes:nil
                                                         error:&error])
    {
        NSLog(@"Create directory error: %@", error);
    }
}

+ (void)createTextFile:(NSString*)fileName data:(NSString*)data
{
    NSString *filePath = [[SharedMemory getDocumentsDir] stringByAppendingPathComponent:fileName];
    [SharedMemory createTextFileFullPath:filePath data:data];
}

+ (void)createTextFileFullPath:(NSString*)filePath data:(NSString*)data
{
    // For error information
    NSError *error;
    
    // Write the file
    // Show contents of Documents directory
    if (![data writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error])
        NSLog(@"Create file error: %@", error);
    NSLog(@"Documents directory: %@", [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[SharedMemory getDocumentsDir] error:&error]);
}

+ (NSString*)getDocumentsDir
{
    NSString *path = [((SharedMemory*)[SharedMemory sharedInstance]).documentsPath stringByAppendingPathComponent:DATA_DIRECTORY];
    return path;
}

+ (void) fillPathNamesArraysWithPathNamesPDVs:(NSMutableArray*) pathNamesPDVs pathNamesAudits:(NSMutableArray*) pathNamesAudits
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray* filesPaths = [fileManager contentsOfDirectoryAtPath:[SharedMemory getDocumentsDir] error:nil];
    for (NSString* filePath in filesPaths) {
        NSString* name = [fileManager displayNameAtPath:filePath];
        if(pathNamesPDVs!=nil && [name hasPrefix:PDV_FILE_PREFIX] )
            [pathNamesPDVs addObject:name];
        else if (pathNamesAudits!=nil && [name hasPrefix:AUDIT_FILE_PREFIX] )
            [pathNamesAudits addObject:name];
    }
}

+ (void) deleteAllFilesForPDVs:(bool) deletePDVs forAudits:(bool) deleteAudits
{
    NSMutableArray* pathsPDVsToDelete = deletePDVs? [[[NSMutableArray alloc] init] autorelease] : nil;
    NSMutableArray* pathsAuditsToDelete = deleteAudits? [[[NSMutableArray alloc] init] autorelease] : nil;
    [SharedMemory fillPathNamesArraysWithPathNamesPDVs:pathsPDVsToDelete pathNamesAudits:pathsAuditsToDelete ];
    if (pathsPDVsToDelete!=nil)
        [SharedMemory deleteListOfNames: pathsPDVsToDelete];
    if (pathsAuditsToDelete!=nil)
        [SharedMemory deleteListOfNames: pathsAuditsToDelete];
}

+ (void) deleteListOfNames:(NSArray*) listOfNames
{
    for (NSString* _name in listOfNames) {
        [SharedMemory deletePathName:_name];
    }
}

+ (void) deletePathName:(NSString*) _name
{
    NSString *filePath = [[SharedMemory getDocumentsDir] stringByAppendingPathComponent:_name];
    [[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
}

+ (void) showError:(NSString *)title andText:(NSString *) desc
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:desc delegate:self  cancelButtonTitle:@"Aceptar" otherButtonTitles:nil,nil];
    [alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:NO];
    [alert release];
}

-(void) resetAuditTypesDone
{
    for (int i=0; i < [self.auditTypesDone count]; i++) {
        [self.auditTypesDone setObject:[NSNumber numberWithBool:false] atIndexedSubscript:i];
    }
}

- (void) forgetKeyOn:(NSString*) defaultsDicKey key:(NSString*) key
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary* dicMut = [[[defaults objectForKey:defaultsDicKey] mutableCopy] autorelease];
    [dicMut removeObjectForKey:key];
    [defaults setObject:dicMut  forKey:defaultsDicKey];
    [defaults synchronize];
}

+ (void) forgetAllKeysOn:(NSString*) defaultsDicKey
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary* dicMut = [[[NSMutableDictionary alloc] init] autorelease];
    [defaults setObject:dicMut  forKey:defaultsDicKey];
    [defaults synchronize];
}

- (void) rememberStringOn:(NSString*) defaultsDicKey key:(NSString*) key value:(NSString*) value
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary* dicMut = [[[defaults objectForKey:defaultsDicKey] mutableCopy] autorelease];
    [dicMut setObject:value forKey:key];
    [defaults setObject:dicMut  forKey:defaultsDicKey];
    [defaults synchronize];
}

+ (void) rememberTodayOn:(NSString*) key
{
    //TODO: aplicarlos donde van!! en sync y en fetch
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970] ]  forKey:key];
    [defaults synchronize];
}

- (bool) isOlderThanAMonth:(NSString*) dateString
{
    NSCalendar* calendar = [NSCalendar currentCalendar];
    
    NSDate *currentDate = [NSDate date];
    NSDateComponents* components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:currentDate]; // Get necessary date components
    
    NSDate *targetDate = [NSDate dateWithTimeIntervalSince1970:[dateString doubleValue]];
    NSDateComponents* targetComponents = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:targetDate]; // Get necessary date components
    
    if ( ([targetComponents year] == [components year]) &&
        ([targetComponents month] == [components month])) {
        return false;
    }
    return true;
}

- (NSString*) makeOwnPDVnId
{
    return [self makePDVnId:[self getPointOfSell]];
}

- (NSString*) makePDVnId:(PointOfSell*)pdv
{
    return [NSString stringWithFormat:@"%@",pdv.name ];
}

- (NSString*) makePDVnTypeId:(PointOfSell*)pdv auditType:(AuditType*)auditType
{
    return [NSString stringWithFormat:@"%@__%@",pdv.name,auditType.name ];
}


- (NSString*) makeOwnPDVnTypeId
{
    return [self makePDVnTypeId:[self getPointOfSell] auditType:[self getAuditType]];
}

#pragma mark - Singleton administration

// Get the shared instance and create it if necessary.
+ (SharedMemory *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[super allocWithZone:NULL] init];
    }
    
    return sharedInstance;
}

// We don't want to allocate a new instance, so return the current one.
+ (id)allocWithZone:(NSZone*)zone {
    return [[self sharedInstance] retain];
}

// Equally, we don't want to generate multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

// Once again - do nothing, as we don't have a retain counter for this object.
- (id)retain {
    return self;
}

// Replace the retain counter so we can never release this object.
- (NSUInteger)retainCount {
    return NSUIntegerMax;
}

// This function is empty, as we don't want to let the user release this object.
- (oneway void)release {
    
}

//Do nothing, other than return the shared instance - as this is expected from autorelease.
- (id)autorelease {
    return self;
}

@end
